package com.guigu.qingcheng.orderservice.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guigu.qingcheng.orderservice.mapper.TbOrderConfigMapper;
import com.guigu.qingcheng.orderservice.mapper.TbOrderLogMapper;
import com.guigu.qingcheng.orderservice.mapper.TbOrderMapper;
import com.guigu.qingcheng.orderservice.service.CartSerivce;
import com.guigu.qingcheng.orderservice.service.GoodsFeign;
import com.guigu.qingcheng.orderservice.service.TbOrderItemService;
import com.guigu.qingcheng.orderservice.service.TbOrderService;
import com.guigu.qingcheng.pojo.order.TbOrder;
import com.guigu.qingcheng.pojo.order.TbOrderConfig;
import com.guigu.qingcheng.pojo.order.TbOrderItem;
import com.guigu.qingcheng.pojo.order.TbOrderLog;
import com.guigu.qingcheng.utils.IdWorker;
import com.guigu.qingcheng.utils.R;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author testjava
 * @since 2020-07-08
 */
@Service
public class TbOrderServiceImpl extends ServiceImpl<TbOrderMapper, TbOrder> implements TbOrderService {

    @Resource
    private TbOrderConfigMapper tbOrderConfigMapper;
    @Resource
    private TbOrderLogMapper tbOrderLogMapper;
    @Resource
    private TbOrderService tbOrderService;
    @Resource
    private TbOrderItemService tbOrderItemService;
    @Resource
    private IdWorker idWorker;
    @Autowired
    private CartSerivce cartSerivce;
    @Resource
    private GoodsFeign feign;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public List<TbOrder> findOrderByUsername(String username) {
        QueryWrapper<TbOrder> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("username",username);
        return tbOrderService.list(wrapper1);
    }

    @Override
    public R findPage(Integer page, Integer size, Map<String, Object> searchMap) {
        Page<TbOrder> tbOrderPage = new Page<>(page,size);
        QueryWrapper<TbOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("is_delete",0);
        if (searchMap != null) {
            if (searchMap.get("id") != null && !"".equals(searchMap.get("id")))
                wrapper.eq("id",searchMap.get("id"));
            if (searchMap.get("receiverContact") != null && !"".equals(searchMap.get("receiverContact")))
                wrapper.like("receiver_contact",searchMap.get("receiverContact"));
            if (searchMap.get("createTime") != null && !"".equals(searchMap.get("createTime")))
                wrapper.ge("create_time",searchMap.get("createTime"));
            if (searchMap.get("createTime1") != null && !"".equals(searchMap.get("createTime1")))
                wrapper.le("create_time",searchMap.get("createTime1"));
            if (searchMap.get("consignStatus") != null && !"".equals(searchMap.get("consignStatus")))
                wrapper.eq("consign_status",searchMap.get("consignStatus"));
            if (searchMap.get("orderOtatus") != null && !"".equals(searchMap.get("orderOtatus")))
                wrapper.eq("order_status",searchMap.get("orderOtatus"));

        }
        baseMapper.selectPage(tbOrderPage,wrapper);
        return R.ok().data("total",tbOrderPage.getTotal()).data("rows",tbOrderPage.getRecords());
    }

    @Override
    public R findById(String ids) {
        List<TbOrder> list = new ArrayList<>();
        String[] split = ids.split(",");
        for(String str:split){
            QueryWrapper<TbOrder> wrapper=new QueryWrapper<>();
            wrapper.eq("id",str);
            wrapper.eq("order_status",1);
            TbOrder tbOrder = baseMapper.selectOne(wrapper);
            if (tbOrder != null) {
                list.add(baseMapper.selectOne(wrapper));
            }
        }
        return R.ok().data("order",list);
    }

    @Override
    public R updates(List<TbOrder> tbOrders) {
        for(TbOrder tbOrder:tbOrders){
           tbOrder.setOrderStatus("2");
           tbOrder.setConsignStatus("1");
           tbOrder.setConsignTime(new Date());
            TbOrderLog log = new TbOrderLog();
            log.setOperater("system");
            log.setOperateTime(new Date());
            log.setOrderId(tbOrder.getId());
            log.setOrderStatus("2");
            log.setPayStatus(tbOrder.getPayStatus());
            log.setConsignStatus("1");
            log.setRemarks("发货");
            tbOrderLogMapper.insert(log);
           baseMapper.updateById(tbOrder);
       }
       return R.ok();
    }

    @Override
    public R updatedown(List<TbOrder> tbOrders) {
        for(TbOrder tbOrder:tbOrders){
            if (tbOrder.getOrderStatus().equals("0")) {
                tbOrder.setOrderStatus("4");
                tbOrder.setCloseTime(new Date());
                TbOrderLog log = new TbOrderLog();
                log.setOperater("system");
                log.setOperateTime(new Date());
                log.setOrderId(tbOrder.getId());
                log.setOrderStatus("4");
                log.setPayStatus(tbOrder.getPayStatus());
                log.setConsignStatus(tbOrder.getConsignStatus());
                log.setRemarks("手动关闭订单");
                tbOrderLogMapper.insert(log);

                baseMapper.updateById(tbOrder);
            }
        }
        return R.ok();
    }

    @Override
    public R updateDelete(List<TbOrder> tbOrders) {
        for(TbOrder tbOrder:tbOrders){
            if (tbOrder.getOrderStatus().equals("4")) {
                tbOrder.setIsDelete("1");
                tbOrder.setCloseTime(new Date());
                TbOrderLog log = new TbOrderLog();
                log.setOperater("system");
                log.setOperateTime(new Date());
                log.setOrderId(tbOrder.getId());
                log.setOrderStatus("4");
                log.setPayStatus(tbOrder.getPayStatus());
                log.setConsignStatus(tbOrder.getConsignStatus());
                log.setRemarks("删除订单");
                tbOrderLogMapper.insert(log);
                baseMapper.updateById(tbOrder);
            }
        }
        return R.ok();
    }

    @Override
    public void orderTimeOutLogic() {
        //查询超时时间
        TbOrderConfig tbOrderConfig = tbOrderConfigMapper.selectById(1);

        //超时时间（分） 60
        Integer orderTimeout = tbOrderConfig.getOrderTimeout();

        //得到超时的时间点
        LocalDateTime localDateTime = LocalDateTime.now().minusMinutes(orderTimeout);

        QueryWrapper<TbOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("order_status","0"); //未付款的
        wrapper.eq("is_delete","0"); //未删除的
        wrapper.lt("create_time",localDateTime);//创建时间小于超时时间

        //查询超时订单
        List<TbOrder> list = tbOrderService.list(wrapper);
        for (TbOrder order: list) {
            //往日志表插入数据
            TbOrderLog log = new TbOrderLog();
            log.setOperater("system");
            log.setOperateTime(new Date());
            log.setOrderStatus("4");
            log.setPayStatus(order.getPayStatus());
            log.setConsignStatus(order.getConsignStatus());
            log.setRemarks("超时订单,系统自动关闭");
            log.setOrderId(order.getId());
            tbOrderLogMapper.insert(log);
            //更改订单状态
            order.setOrderStatus("4");
            order.setCloseTime(new Date());
            baseMapper.updateById(order);
        }
    }

    @Override
    public R updateqrsh(TbOrder tbOrder) {
                tbOrder.setUpdateTime(new Date());
                tbOrder.setEndTime(new Date());
                tbOrder.setOrderStatus("4");
                tbOrder.setCloseTime(new Date());
                TbOrderLog log = new TbOrderLog();
                log.setOperater("system");
                log.setOperateTime(new Date());
                log.setOrderId(tbOrder.getId());
                log.setOrderStatus("3");
                log.setPayStatus(tbOrder.getPayStatus());
                log.setConsignStatus(tbOrder.getConsignStatus());
                log.setRemarks("手动确认收货");
                tbOrderLogMapper.insert(log);
                baseMapper.updateById(tbOrder);
        return R.ok();
    }

    @Override
    public R yjupdateqrsh(List<TbOrder> tbOrders) {
        for(TbOrder tbOrder:tbOrders){
            tbOrder.setUpdateTime(new Date());
            tbOrder.setEndTime(new Date());
            tbOrder.setOrderStatus("4");
            tbOrder.setCloseTime(new Date());
            TbOrderLog log = new TbOrderLog();
            log.setOperater("system");
            log.setOperateTime(new Date());
            log.setOrderId(tbOrder.getId());
            log.setOrderStatus("3");
            log.setPayStatus(tbOrder.getPayStatus());
            log.setConsignStatus(tbOrder.getConsignStatus());
            log.setRemarks("一键确认收货");
            tbOrderLogMapper.insert(log);
            baseMapper.updateById(tbOrder);
        }
        return R.ok();
    }

    @Override
    public R findByConsignStatus() {
        QueryWrapper<TbOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("consign_status",0);
        wrapper.eq("is_delete",0);
        List<TbOrder> tbOrders = baseMapper.selectList(wrapper);
        return R.ok().data("list",tbOrders);
    }

    @Override
    public R hbOrder(String id, String id1) {
        TbOrder order = baseMapper.selectById(id);
        TbOrder order1 = baseMapper.selectById(id1);
        order.setTotalNum(order.getTotalNum()+order1.getTotalNum());
        order.setTotalMoney(order.getTotalMoney()+order1.getTotalMoney());
        order.setPayMoney(order.getPayMoney()+order1.getPayMoney());
        order.setUpdateTime(new Date());
        List<TbOrderItem> byOrderId = tbOrderItemService.findByOrderId(id1);
        for (TbOrderItem tbOrderItem:byOrderId) {
            TbOrderItem orderItem = tbOrderItem.setOrderId(order.getId());
            tbOrderItemService.updateById(orderItem);
        }
        order1.setIsDelete("1");
        baseMapper.updateById(order);
        baseMapper.updateById(order1);
        TbOrderLog log = new TbOrderLog();
        log.setOperater("system");
        log.setOperateTime(new Date());
        log.setOrderId(order.getId());
        log.setOrderStatus(order.getOrderStatus());
        log.setPayStatus(order.getPayStatus());
        log.setConsignStatus(order.getConsignStatus());
        log.setRemarks("合并订单");
        tbOrderLogMapper.insert(log);
        return R.ok();
    }

    @Override
    public R updateOrder(TbOrder tbOrder,String remarks) {
        baseMapper.updateById(tbOrder);
        TbOrderLog log = new TbOrderLog();
        log.setOperater("system");
        log.setOperateTime(new Date());
        log.setOrderId(tbOrder.getId());
        log.setOrderStatus(tbOrder.getOrderStatus());
        log.setPayStatus(tbOrder.getPayStatus());
        log.setConsignStatus(tbOrder.getConsignStatus());
        log.setRemarks(remarks);
        tbOrderLogMapper.insert(log);
        return R.ok();
    }

    @Override
    public void orderTimeOutSh() {
        //查询超时时间
        TbOrderConfig tbOrderConfig = tbOrderConfigMapper.selectById(1);

        //超时时间（分） 60
        Integer orderTimeout = tbOrderConfig.getTakeTimeout();

        //得到超时的时间点
        LocalDateTime localDateTime = LocalDateTime.now().minusDays(orderTimeout);

        QueryWrapper<TbOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("order_status","3"); //已完成的
        wrapper.eq("is_delete","0"); //未删除的
        wrapper.lt("create_time",localDateTime);//创建时间小于超时时间

        //查询超时订单
        List<TbOrder> list = tbOrderService.list(wrapper);
        for (TbOrder order: list) {
            //往日志表插入数据
            TbOrderLog log = new TbOrderLog();
            log.setOperater("system");
            log.setOperateTime(new Date());
            log.setOrderStatus("4");
            log.setPayStatus(order.getPayStatus());
            log.setConsignStatus(order.getConsignStatus());
            log.setRemarks("自动收货");
            log.setOrderId(order.getId());
            tbOrderLogMapper.insert(log);
            //更改订单状态
            order.setOrderStatus("4");
            order.setCloseTime(new Date());
            baseMapper.updateById(order);
        }
    }

    @Override
    public R findByOrderId(String id) {
        QueryWrapper<TbOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("id",id);
        wrapper.eq("is_delete",0);
        TbOrder order = baseMapper.selectOne(wrapper);
        if (order != null) {
            List<TbOrderItem> orderItem = tbOrderItemService.findByOrderId(order.getId());
            return R.ok().data("list",orderItem);
        }
        return R.error();
    }

    /**
     * 新增
     * @param order
     * @return
     */
    @Override
    @Transactional
    public Map<String, Object> add(TbOrder order) {
        //获取购物车(刷新单价)
        List<Map<String, Object>> list = cartSerivce.findNewOrderItemList(order.getUsername());
        List<TbOrderItem> items = list.stream().filter(cart -> (boolean) cart.get("checked"))
                .map(cart -> (TbOrderItem) cart.get("item")).collect(Collectors.toList());
        //扣减库存
        if (!feign.deductionStock(items)) {
            throw new RuntimeException("库存扣减失败");
        }
        try {
            //保存订单主表
            order.setId(idWorker.nextId() + "");
            //合计数计算
            IntStream num = items.stream().mapToInt(TbOrderItem::getNum);
            IntStream money = items.stream().mapToInt(TbOrderItem::getMoney);
            //总数量
            int totalNum = num.sum();
            //总金额
            int totalMoney = money.sum();
            //计算优惠金额
            int preMoney = cartSerivce.preferential(order.getUsername());
            //总数量
            order.setTotalNum(totalNum);
            //总金额
            order.setTotalMoney(totalMoney);
            order.setPreMoney(preMoney);
            order.setPayMoney(totalMoney - preMoney);
            order.setCreateTime(new Date());
            order.setOrderStatus("0");
            order.setPayStatus("0");
            order.setConsignStatus("0");
            order.setIsDelete("0");
            baseMapper.insert(order);

            double pro = order.getPayMoney() / totalMoney;
            //保存订单明细
            for (TbOrderItem orderItem : items) {
                orderItem.setOrderId(order.getId());
                orderItem.setId(idWorker.nextId() + "");
                //应付金额
                orderItem.setPayMoney((int) (orderItem.getMoney() * pro));
                tbOrderItemService.save(orderItem);
            }
            //清除选中购物车
            cartSerivce.deleteCheckedCart(order.getUsername());
            //返回订单号和支付的金额
            Map<String, Object> map = new HashMap();
            map.put("ordersn", order.getId());
            map.put("money", order.getPayMoney());
            return map;
        }catch (Exception ex){
            rabbitTemplate.convertAndSend("","queue.back", JSON.toJSONString(items));
            //抛出异常,让其回滚
            throw new RuntimeException("生成订单失败");
        }
    }

}
